package com.nightpiter.view.drawer.advanced;

import java.util.ArrayList;
import java.util.Collection;

import android.graphics.Point;

import com.nightpiter.model.objects.HubComponent;
import com.nightpiter.model.objects.Hub;
import com.nightpiter.model.objects.Station;
import com.nightpiter.model.objects.Transfer;
import com.nightpiter.model.objects.Tunnel;

/**
 * 
 * Some methods to prepare hubs for drawing
 * 
 * @author Alexandr Melamud
 * 
 */

public class HubResolver {

	public static void extractHubComponents(Collection<Hub> hubs) {

		for (Hub hub : hubs) {
			for (Station station : hub.getStations()) {
				if (componentOfStation(station, hub) == null) {
					HubComponent component = new HubComponent();
					component.addStation(station);

					for (Transfer transfer : station.getTransfers()) {
						if (componentOfStation(transfer.getToStation(),
								hub) == null) {
							if (ableToAddToComponent(transfer
									.getToStation(), component)) {
								component.addStation(transfer.getToStation());
							}
						}
						if (componentOfStation(transfer.getToStation(),
								hub) != null) {
							if (componentOfStation(transfer.getToStation(), hub)
									.equals(component) == false) {
								componentOfStation(transfer.getToStation(), hub)
										.addComponentUnited(component);
								component
										.addComponentUnited(componentOfStation(
												transfer.getToStation(), hub));
							}

						}
					}
					hub.addComponentOfHub(component);
				}
			}
		}
	}

	public static Hub stationIsInHubs(Station station) {

		for (Transfer transfer : station.getTransfers()) {
			if (transfer.getHub() != null) {
				return transfer.getHub();
			}
		}
		return null;
	}

	public static boolean ableToAddToComponent(Station station,
			HubComponent component) {
		boolean available = false;
		ArrayList<Boolean> check = new ArrayList<Boolean>();
		for (Station stat : component.getStations()) {
			boolean trueOrFalse = false;
			float distX = Math.signum(station.getPosition().x
					- stat.getPosition().x)
					* (station.getPosition().x - stat.getPosition().x);
			float distY = Math.signum(station.getPosition().y
					- stat.getPosition().y)
					* (station.getPosition().y - stat.getPosition().y);
			if (backTransferIsInTransferList(station, stat.getTransfers())
					& (distX <= 2) & (distY <= 2)) {
				trueOrFalse = true;
			}
			check.add(trueOrFalse);
		}

		if (!check.contains(false)) {
			available = true;
		}
		return available;
	}

	public static boolean backTransferIsInTransferList(Station station,
			Collection<Transfer> transferList) {
		boolean available = false;
		for (Transfer trans : transferList) {
			if (trans.getToStation().equals(station)) {
				available = true;
				return available;
			}
		}
		return available;
	}

	public static HubComponent componentOfStation(Station station, Hub hub) {
		for (HubComponent component : hub.getComponents()) {
			if (component.getStations().contains(station)) {
				return component;
			}
		}
		return null;
	}

	public static Point componentCoordinates(HubComponent component) {

		int x = 0;
		int y = 0;
		for (Station station : component.getStations()) {
			x += station.getPosition().x;
			y += station.getPosition().y;
		}

		return new Point((int) x / component.getStations().size(), (int) y
				/ component.getStations().size());
	}

	public static ArrayList<Integer> colorsInComponent(HubComponent component) {
		ArrayList<Integer> colors = new ArrayList<Integer>();

		for (Station station : component.getStations()) {
			for (Tunnel tunnel : station.getTunnels()) {
				if (colors.contains(tunnel.getLine().getColor()) == false) {
					colors.add(tunnel.getLine().getColor());
				}
			}
		}
		return colors;
	}

}
